home *** CD-ROM | disk | FTP | other *** search
- Path: xanth!nic.MR.NET!hal!ncoast!allbery
- From: lew@gsg.UUCP (Paul Lew)
- Newsgroups: comp.sources.misc
- Subject: v05i084: submission to comp.sources.misc
- Message-ID: <8812161819.AA28588@gsg.UUCP>
- Date: 19 Dec 88 00:18:22 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: lew@gsg.UUCP (Paul Lew)
- Lines: 521
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 5, Issue 84
- Submitted-by: "Paul Lew" <lew@gsg.UUCP>
- Archive-name: pt.bsd
-
- Newsgroups: comp.sources.misc
- Keywords: ps BSD process tree
- Message-ID: <290@gsg.UUCP>
- Date: 16 Dec 88 17:39:57 GMT
- Organization: General Systems Group, Inc., Salem, NH
- Lines: 511
-
- ptree,pt: BSD ps backend filter to display process tree
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # README
- # ptree.c
- # Kill
- # This archive created: Fri Dec 16 12:22:07 1988
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'README'" '(2009 characters)'
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'README'
- X Ptree Version 1.0 05/24/88
- X
- XIntroduction:
- X
- X ptree is a backend filter for BSD 'ps' command. It reads the
- X output from ps and produces process tree graph on the standard
- X output with each process indented under its parent. This program
- X was inspired by the 'utree' program for system V from Brandon
- X Allbery. The following is an example:
- X
- X $ ptree ag | grep -v getty
- X USER STAT TTY TIME COMMAND
- X lew I i14 0:09 -Tcsh (Tcsh)
- X lew I i14 0:31 | emacs
- X lew I p0 0:00 | | /usr/local/emacs/etc/loadst -n 60
- X alice I i17 0:03 -csh (csh)
- X lew I i18 0:08 -Tcsh (Tcsh)
- X lew S i18 0:09 | screen -e?]
- X lew I p1 0:06 | | -bin/Tcsh (Tcsh)
- X lew S p2 0:07 | | -bin/Tcsh (Tcsh)
- X domino S i26 0:05 -csh (csh)
- X domino S i26 0:00 | lprint -f /usr/local/bin/lprint -n BigBucks
- X domino S i26 0:00 | | dcat -d 3 -b 128
- X mxt I i27 0:02 -csh (csh)
- X mxt I i27 0:03 | mail -f
- X mxt I i27 0:00 | | sh -c /usr/ucb/more
- X mxt I i27 0:00 | | | /usr/ucb/more
- X
- X This is not 'yet another setuid program'. You dont have to be the
- X root to use it. This is the main reason to write it as a filter.
- X May be BSD can incorporate this into real 'ps' on future release.
- X
- X Kill is a script which uses 'sf' (shell form in comp.sources.unix)
- X to allow one to send signals to processes by context.
- X
- XManual:
- X
- X There is no man page to it, type: 'pt H' will give you simple help
- X message. If you know how 'ps' works then you dont need a manual,
- X if you dont, this might not be useful to you.
- X
- XBuild:
- X
- X cc -o ptree ptree.c
- X ln ptree pt
- X
- XCopyright:
- X
- X No copyright, complete in public domain. Do whatever you like with
- X it. If you can make money from it, great for you.
- X
- X----------------------------------------------------------------------
- XPaul Lew {olivea,harvard,decvax}!gsg!lew (UUCP)
- XGeneral Systems Group, 5 Manor Parkway, Salem, NH 03079 (603) 893-1000
- SHAR_EOF
- if test 2009 -ne "`wc -c < 'README'`"
- then
- echo shar: error transmitting "'README'" '(should have been 2009 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'ptree.c'" '(8883 characters)'
- if test -f 'ptree.c'
- then
- echo shar: will not over-write existing file "'ptree.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'ptree.c'
- Xstatic char *Sccsid = "(File: %M% Ver: %I% Update: %G% %U%)";
- X/*+F***********************************************************************
- X*
- X* File name: ptree.c
- X*
- X* Author: Paul Lew, General Systems Group, Inc. Salem, NH
- X* Created at: 05/22/88 16:10 PM
- X* Last update: 05/24/88 08:54 PM (Edition: 26)
- X*
- X* Description: This program will parse output of 'ps' command and display
- X* the output with process indented under their parents for
- X* the easy identification.
- X*
- X* Environment: 4.2 BSD Unix (Pyramid OSx 4.1)
- X*
- X* Usage: ptree [HPacgxt#]
- X*
- X* Update History:
- X*
- X* Date Description By
- X* -------- ------------------------------------------------ ---
- X* 05/22/88 Initial version Lew
- X*
- X* Routines included:
- X*
- X* build_offset build offset from 1st line of ps output
- X* save_addr return addr of Save array with pid = pid
- X* add_child add child to parent, if exists, add to end of sibling
- X* print_result display result
- X* print_process print a given process sub-tree
- X* dump_save dump save structure for debugging
- X* procarg return command argument for ps command
- X* usage display help message
- X*
- X* Build: cc -o ptree ptree.c <CR>
- X*
- X**-F**********************************************************************/
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X
- X#define YES 1
- X#define NO 0
- X
- X#define MAXLINE 200
- X
- Xstruct save {
- X struct save *so_parent; /* pointer to parent */
- X struct save *so_sibling; /* pointer to 1st sibling */
- X struct save *so_child; /* pointer to 1st child */
- X int so_uid; /* user ID */
- X char so_name[9]; /* user name */
- X int so_pid; /* pid */
- X int so_ppid; /* parent pid */
- X char *so_buffer; /* pointer to ps output */
- X } Save [MAXLINE];
- X
- Xchar *Version = "Version 1.0 05/24/88 00:51 AM";
- Xchar *Author = "Paul Lew, lew@gsg.uucp";
- X
- Xint Line; /* # of output line from ps */
- Xint Print_me = NO; /* if NO, dont print my processes */
- Xint Print_pid = NO; /* if YES, output PID */
- Xchar Command [80];
- Xint My_pid; /* my process id */
- X
- Xint Uid_offset;
- Xint Pid_offset;
- Xint Ppid_offset;
- Xint End_ppid;
- Xint Stat_offset;
- Xint Tyy_offset;
- Xint Command_offset;
- X
- Xstruct save *save_addr ();
- Xchar *procarg ();
- X
- Xextern FILE *popen ();
- Xextern char *malloc (), *calloc ();
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| M a i n R o u t i n e S t a r t s H e r e |
- X| |
- X+----------------------------------------------------------------------*/
- Xmain (argc, argv)
- Xint argc;
- Xchar **argv;
- X {
- X FILE *pfd; /* file descriptor for popen() */
- X char *p; /* temp pointer to malloced buffer */
- X register int i; /* loop index */
- X register struct save *svp;
- X
- X p = procarg (argc, argv);
- X sprintf (Command, "ps lw%s", p);
- X if ((pfd = popen (Command, "r")) == NULL) {
- X fprintf (stderr, "can not execture ps\n");
- X exit (1);
- X }
- X for (Line=0; Line<MAXLINE; Line++) {
- X p = malloc (BUFSIZ);
- X if (p == NULL) {
- X perror ("malloc");
- X exit (1);
- X }
- X if (fgets (p, BUFSIZ, pfd) == NULL) break;
- X Save[Line].so_buffer = p;
- X if (Line == 0) build_offset (p);
- X else /* prevent CP data being processed */
- X p[End_ppid] = '\0';
- X }
- X pclose (pfd);
- X for (i=1; i<Line; i++) {
- X struct passwd *pwp;
- X svp = &Save[i];
- X svp->so_pid = atoi (&svp->so_buffer[Pid_offset]);
- X svp->so_ppid = atoi (&svp->so_buffer[Ppid_offset]);
- X svp->so_uid = atoi (&svp->so_buffer[Uid_offset]);
- X pwp = getpwuid (svp->so_uid);
- X strncpy (svp->so_name, pwp->pw_name, 8);
- X }
- X for (i=1; i<Line; i++) {
- X struct save *p;
- X svp = &Save[i];
- X svp->so_parent = p = save_addr (svp->so_ppid);
- X if (p) {
- X add_child (p, svp);
- X }
- X }
- X print_result ();
- X#ifdef DEBUG
- X dump_save ();
- X#endif
- X exit (0);
- X }
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| build_offset : build offset from 1st line of ps output |
- X| |
- X+----------------------------------------------------------------------*/
- Xbuild_offset (buf)
- Xchar *buf; /* header line */
- X {
- X char *p = buf;
- X for (p=buf; *p != '\0'; p++) {
- X if (strncmp ("UID", p, 3) == 0) Uid_offset = p-buf;
- X else if (strncmp (" PID ", p, 6) == 0) Pid_offset = p-buf;
- X else if (strncmp (" PPID ", p, 6) == 0) Ppid_offset = p-buf;
- X else if (strncmp ("STAT", p, 4) == 0) Stat_offset = p-buf;
- X else if (strncmp ("TTY", p, 3) == 0) Tyy_offset = p-buf;
- X else if (strncmp ("COMMAND",p, 7) == 0) Command_offset = p-buf;
- X }
- X End_ppid = Ppid_offset + 5;
- X }
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| save_addr : return addr of Save array with pid = pid |
- X| |
- X+----------------------------------------------------------------------*/
- Xstruct save *
- Xsave_addr (pid)
- Xint pid;
- X {
- X register int i;
- X for (i=1; i<Line; i++) {
- X if (Save[i].so_pid == pid) return (&Save[i]);
- X }
- X return (NULL); /* not found */
- X }
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| add_child : add child to parent, if exists, add to end of sibling |
- X| |
- X+----------------------------------------------------------------------*/
- Xadd_child (parent, child)
- Xstruct save *parent;
- Xstruct save *child;
- X {
- X if (parent->so_child == NULL) {
- X parent->so_child = child;
- X }
- X else {
- X struct save *tp = parent->so_child;
- X while (tp->so_sibling != NULL) tp = tp->so_sibling;
- X tp->so_sibling = child;
- X }
- X child->so_sibling = NULL;
- X }
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| print_result : display result |
- X| |
- X+----------------------------------------------------------------------*/
- Xprint_result ()
- X {
- X register int i;
- X struct save *svp;
- X
- X My_pid = getpid ();
- X printf ("%s USER %s", Print_pid ? " PID " : "",
- X &Save[0].so_buffer[Stat_offset]);
- X for (i=1; i<Line; i++) {
- X svp = &Save[i];
- X if (svp->so_parent != NULL) {
- X if (svp->so_pid != 0)
- X continue;
- X }
- X print_process (0, svp);
- X }
- X }
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| print_process : print a given process sub-tree |
- X| |
- X+----------------------------------------------------------------------*/
- Xprint_process (level, svp)
- Xint level;
- Xstruct save *svp;
- X {
- X struct save *tp;
- X register int i;
- X
- X if (!Print_me && svp->so_pid == My_pid) return;
- X if (Print_pid) printf ("%5d ", svp->so_pid);
- X printf ("%8s %.*s", svp->so_name, Command_offset - Stat_offset,
- X &svp->so_buffer[Stat_offset]);
- X for (i=0; i<level; i++) printf ("| ");
- X printf ("%s", &svp->so_buffer[Command_offset]);
- X if ((tp = svp->so_child) != NULL) {
- X while (tp != NULL) {
- X if (tp != svp) /* avoid infinit recursion */
- X print_process (level+1, tp);
- X tp = tp->so_sibling;
- X }
- X }
- X }
- X
- X/*-------------------------------------------------------------05/23/88-+
- X| |
- X| dump_save : dump save structure for debugging |
- X| |
- X+----------------------------------------------------------------------*/
- X#ifdef DEBUG
- Xdump_save ()
- X {
- X register int i;
- X register struct save *tp;
- X
- X for (i=1; i<Line; i++) {
- X tp = &Save[i];
- X printf ("parent=%08x(x) ", tp->so_parent);
- X printf ("sibling=%08x(x) ", tp->so_sibling);
- X printf ("child=%08x(x) ", tp->so_child);
- X printf ("PID=%05d PPID=%05d\n", tp->so_pid, tp->so_ppid);
- X }
- X printf ("command: [%s]\n", Command);
- X }
- X#endif
- X
- X/*------------------------------------------------------------05/24/88--+
- X| |
- X| procarg : return command argument for ps command |
- X| |
- X+----------------------------------------------------------------------*/
- Xchar *
- Xprocarg (argc, argv)
- Xint argc;
- Xchar **argv;
- X {
- X static char buf [20] = "";
- X register char c;
- X register char *p = argv[1];
- X int i = 0;
- X
- X if (argc == 1) return (buf);
- X while ((c = *p++) != '\0') {
- X switch (c) {
- X case 'P': Print_me = YES; break;
- X case 'p': Print_pid = YES; break;
- X case 'H': usage (argv[0]); exit (0);
- X case 'a': case 'c': case 'e': case 'g':
- X case 'x': buf[i++] = c; break;
- X case 't': strcpy (&buf[i], p-1); return (buf);
- X default: usage (argv[0]); exit (1);
- X }
- X }
- X buf [i] = '\0';
- X return (buf);
- X }
- X
- X/*-------------------------------------------------------------07/01/86-+
- X| |
- X| usage : display help message |
- X| |
- X+----------------------------------------------------------------------*/
- Xstatic usage (pname)
- Xchar *pname; /* program name */
- X {
- X fprintf (stderr, "%s %s %s\n", pname, Version, Author);
- X fprintf (stderr, "Usage: %s [acepgtxHP]\n", pname);
- X fprintf (stderr, "where options:\n");
- X fprintf (stderr, " H display this help message\n");
- X fprintf (stderr, " P print processes created by me\n");
- X fprintf (stderr, " p output PID\n");
- X fprintf (stderr, " a,c,e,g,t,x will be passed to ps, if t is\n");
- X fprintf (stderr, " specified, all the rest char in\n");
- X fprintf (stderr, " the argument will be copied\n");
- X }
- SHAR_EOF
- if test 8883 -ne "`wc -c < 'ptree.c'`"
- then
- echo shar: error transmitting "'ptree.c'" '(should have been 8883 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'Kill'" '(2925 characters)'
- if test -f 'Kill'
- then
- echo shar: will not over-write existing file "'Kill'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'Kill'
- X#! /bin/csh -f
- X#
- X#- Kill - kill process with shell form interface
- X#-
- X#- This program will use shell form to display current user's
- X#- process generated by ptree command. You can tab to the
- X#- desired process and select proper signal to be sent to the
- X#- process. Press return will trigger the action.
- X#-
- X# Author: Paul Lew, General Systems Group, Inc.
- X# Created at: 05/12/88 07:56 PM
- X# Last update: 07/26/88 10:56 AM (Edition: 32)
- X#
- X#- Usage: Kill [string]
- X#- where option:
- X#- string if specified, will do 'ptree ax | grep string'
- X#- and display only matched process.
- X#
- Xset tmpfile = "/tmp/tmpfile.$$"
- Xset sofile = "/tmp/sofile.$$"
- Xset ptfile = "/tmp/ptfile.$$"
- X#---------------------------------------------------------------#
- X# Display help if requested by user #
- X#---------------------------------------------------------------#
- Xswitch ( "$1" )
- X case -H[xX]:
- X set echo; set verbose; shift
- X breaksw
- X case -H*:
- X show_help `which $0` $1
- X goto end
- X default:
- X endsw
- X#---------------------------------------------------------------#
- X# Process Arguments #
- X#---------------------------------------------------------------#
- Xset greparg = '.'
- Xset ptflag = 'x'
- Xif ( "$1" != '' ) then
- X set greparg = $1
- X set ptflag = 'ax'
- X endif
- X#---------------------------------------------------------------#
- X# Create sf description file #
- X#---------------------------------------------------------------#
- Xpt p$ptflag > $tmpfile
- Xtr '~' '?' < $tmpfile | sed -n \
- X -e '1s/COMMAND/SIGNAL &/p;1d' \
- X -e '/Kill/d' \
- X -e "/$greparg/"'{;s/^\(..............................\)\(.*\)$/\1~~~~~~ \2/p;}' \
- X > $ptfile
- Xsed 's/^......//' $ptfile | colrm 80 > $tmpfile
- X@ lcount = `cat $tmpfile | wc -l`
- X@ lcount--
- Xif ( $lcount == 0 ) then
- X echo "...Pattern $greparg not found in pt list, aborted..."
- X goto end
- X endif
- Xcat << cat_eof >> $tmpfile
- X
- X[TAB (next process), SPACE (next signal), - (no signal), RETURN (execute)]
- X
- Xcat_eof
- X@ i = 0
- Xset sig = "/- /HUP/INT/QUIT/ILL/TRAP/ABRT/EMT/FPE/KILL/BUS/SEGV/SYS"
- Xset sig = "$sig/PIPE/ALRM/TERM/URG/STOP/TSTP/CONT/CHLD/TTIN/TTOU/IO/XCPU"
- Xset sig = "$sig/XFSZ/VTALRM/PROF/USR1/USR2/PWR/LOST/"
- Xwhile ( $i < $lcount )
- X @ i++
- X echo ".v=var$i.s=$sig." >> $tmpfile
- X end
- X#---------------------------------------------------------------#
- X# run sf to get user input #
- X#---------------------------------------------------------------#
- Xsf -u -o $sofile < $tmpfile
- Xif ( ! -e $sofile ) goto end
- Xsource $sofile
- X@ i = 0
- Xwhile ( $i < $lcount )
- X @ i++
- X set var = `eval echo \$var$i`
- X if ( "$var" != '-' ) then
- X @ line = $i + 1
- X kill -$var `sed -n "$line"'s/^ *\([0-9]*\).*$/\1/p' $ptfile`
- X endif
- X end
- X#---------------------------------------------------------------#
- X# Clean up and exit here... #
- X#---------------------------------------------------------------#
- Xend:
- X /bin/rm -f $tmpfile $sofile $ptfile
- X unset tmpfile sofile ptfile i lcount var line greparg ptflag
- SHAR_EOF
- if test 2925 -ne "`wc -c < 'Kill'`"
- then
- echo shar: error transmitting "'Kill'" '(should have been 2925 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-